package icbc.nav.view
{
	import fl.containers.ScrollPane;
	
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.text.StyleSheet;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	import icbc.app.AppGlobal;
	import icbc.app.control.Alert;
	import icbc.app.setting.event.ContentEvent;
	import icbc.app.setting.event.ParserEvent;
	import icbc.app.setting.reader.ContentReader;
	import icbc.nav.Session;
	import icbc.nav.control.BreadCrumbsControl;
	import icbc.nav.control.ContentArrowControl;
	import icbc.nav.control.ContentNavBarreControl;
	import icbc.nav.control.MenuButton;
	import icbc.nav.control.SubContentLabel;
	import icbc.nav.control.TipsControl;
	import icbc.nav.entity.Content;
	import icbc.nav.entity.Menu;
	import icbc.nav.entity.MenuChild;
	import icbc.nav.event.MenuContentEvent;
	import icbc.nav.event.ViewEvent;
	
	import org.osflash.signals.Signal;

	public class ContentView extends View
	{
		public static const EVENT_HOME:String = "contentView.home";
		public static const MAX_IMAGE_WIDTH:uint = 470;
		public static const CONTENT_MARGIN_X:uint = 20;
		private var backgroundImage:String = null;
		private var imageBg:Sprite;
		private var menuData:MenuChild;
		public var content:Content;
		private var image:Sprite;
		private var scrollpane:ScrollPane;
		private var place:Sprite;
		private var scrollPaneWidth:uint = 250;
		private var scrollPaneHeight:uint = 300;
		private var breadCrumbs:BreadCrumbsControl;
		private var tips:TipsControl;
		private var readyLoadCount:int = 0;
		private var fullPath:Array;
		private var navBarre:ContentNavBarreControl;
		private var childList:Array;
		public var onTopLink:Signal = new Signal(String, Array);
		public var onNavClick:Signal = new Signal(MenuChild);
		public var onNavHomeClick:Signal = new Signal();
		public var onReady:Signal = new Signal();
		private var prevButton:ContentArrowControl;
		private var nextButton:ContentArrowControl;
		
		public function ContentView(menuData:MenuChild)
		{
			super();
			this.menuData = menuData;
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(evt:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			stage.addEventListener(Event.RESIZE, initMain);
			stage.dispatchEvent(new Event(Event.RESIZE));
		}
		
		private function initMain(evt:Event = null):void
		{
			if(stage.stageWidth>0)
				stage.removeEventListener(Event.RESIZE, initMain);
			else return;
			imageBg = new Sprite();
			addChild(imageBg);
			readyLoadCount = 2;
			loadBackground();
			loadContent();
		}
		
		public function loadContent():void
		{
			var contentPath:String = getContent();
			var reader:ContentReader = new ContentReader(AppGlobal.combinePath(contentPath));
			reader.addEventListener(ContentEvent.READER_READY, contentReady);
			reader.addEventListener(ContentEvent.ERROR, contentError);
			reader.init();
		}
		
		private function getContent():String
		{
			var contentPath:String = menuData.path;
			if(menuData.indexContent == 0) return contentPath;
			if(menuData.indexContent <= menuData.contents.length)
			{
				contentPath = menuData.contents[menuData.indexContent-1];
			}
			return contentPath;
		}
		
		private function contentError(evt:ContentEvent):void
		{
			var reader:ContentReader = evt.target as ContentReader;
			reader.removeEventListener(ContentEvent.READER_READY, contentReady);
			reader.removeEventListener(ContentEvent.ERROR, contentError);
			dispose();
		}

		private function contentReady(evt:ContentEvent):void
		{
			var reader:ContentReader = evt.target as ContentReader;
			reader.removeEventListener(ContentEvent.READER_READY, contentReady);
			reader.removeEventListener(ContentEvent.ERROR, contentError);
			content = evt.data;
			initContent();
		}

		private function initContent():void
		{
			panel = setBasePanel();
			addChild(panel);
			panel.x = stage.stageWidth/2 - panel.width/2;
			panel.y = stage.stageHeight/2 - panel.height/2;
			
			image = new Sprite();
			panel.addChild(image);
			
			buildPreview();
			initScrollpane();
			initBreadCrumbs();
			initNavBarre();
			//setSubContentMode();
		}
		
		private function homeClickHandler(evt:Event):void
		{
			dispatchEvent(new Event(EVENT_HOME));
			var menuButton:MenuButton = evt.target as MenuButton;
			menuButton.removeEventListener(MenuButton.EVENT_CLICK, homeClickHandler);
			dispose();
		}

		private function buildPreview():void
		{
			if(content.image == null)
				return;
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageComplete);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			loader.load(new URLRequest(AppGlobal.combinePath(content.image)));
			image.addChild(loader);
		}

		private function onIOError(evt:IOErrorEvent):void
		{
			trace("ContentView.Image["+ content.image +"].IOError: "+ evt.text);
		}		
		
		private function imageComplete(evt:Event):void
		{
			var image:DisplayObject = (evt.target as LoaderInfo).content;
			var originalWidth:int = image.width;
			var originalHeight:int = image.height;
			var prefWidth:int = MAX_IMAGE_WIDTH;
			var prefHeight:int = prefWidth/originalWidth*originalHeight;
			image.width = prefWidth
			image.height = prefHeight;
			image.x = CONTENT_MARGIN_X;
			image.y = viewHeight/2 - image.height/2;
			initTips();
			tips.x = image.x;
			tips.y = image.y;
			readyLoadCount--;
			dispatchReady();
		}
		
		private function dispatchReady():void
		{
			if(readyLoadCount == 0)
			{
				dispatchEvent(new ViewEvent(ViewEvent.READY));
				onReady.dispatch();
			}
		}

		private function initScrollpane():void
		{
			var controlWidth:uint = scrollPaneWidth;
			var controlHeight:uint = scrollPaneHeight;
			
			scrollpane = new ScrollPane();
			scrollpane.setSize(controlWidth, controlHeight);
			scrollpane.horizontalScrollPolicy = "off";
			var newSkinClip:Sprite = new Sprite();
			newSkinClip.graphics.clear();
			newSkinClip.graphics.beginFill(0xff0000, 0);
			newSkinClip.graphics.drawRect(0,0,272.0, 191.0);
			newSkinClip.graphics.endFill();
			scrollpane.setStyle("skin", newSkinClip );
			scrollpane.setStyle("upSkin", newSkinClip );
			scrollpane.setStyle("borderColor", 0xFFFFFF);
			scrollpane.setStyle("borderStyle","none");
			scrollpane.drawFocus(false);
			scrollpane.focusRect = null;
			scrollpane.tabEnabled = false;
			panel.addChild(scrollpane);
			
			scrollpane.x = viewWidth - controlWidth - 20;
			scrollpane.y = 60;
			
			place = new Sprite();
			scrollpane.source = place;
			initPlace();
		}

		private function initPlace():void
		{
			var textfield:TextField = buildContentText(content.text);
			place.addChild(textfield);
			scrollpane.refreshPane();
			scrollpane.invalidate();
			textfield.autoSize = TextFieldAutoSize.NONE;
			textfield.height += 1;
		}
		
		private function buildContentText(text:String):TextField
		{
			var txtWidth:uint = scrollPaneWidth-15;
			var txtHeight:uint = 290;
			var format:TextFormat = new TextFormat();
			format.font = AppGlobal.FONT_NAME;
			format.color = AppGlobal.FONT_COLOR;
			format.size = AppGlobal.FONT_SMALL_SIZE;
			format.align = "left";
			format.leading = AppGlobal.CONTENT_TEXT_LEADING;

			var txt:TextField = new TextField();
			txt.selectable = true;
			txt.width = txtWidth;
			txt.height = txtHeight;
			txt.defaultTextFormat = format;
			txt.multiline = true;
			txt.wordWrap = true;
			txt.border = false;
			txt.autoSize = TextFieldAutoSize.LEFT;
			txt.styleSheet = getStyle();
			
			var htmltext:String = 
				"<textformat leading='"
				+ AppGlobal.CONTENT_TEXT_LEADING +"'>"
				+ text 
				+"<textformat>";
			
			txt.htmlText = htmltext;
			return txt;
		}
		
		private function getStyle():StyleSheet
		{
			var style:StyleSheet = new StyleSheet();
			style.setStyle("li", {});
			style.setStyle("h1", {leading:0, marginLeft:20});
			return style;
		}
		
		private function initBreadCrumbs():void
		{
			setFullPath();
			breadCrumbs = new BreadCrumbsControl(fullPath);
			breadCrumbs.onClick.add(topLinkHandler);
			panel.addChild(breadCrumbs);
			breadCrumbs.x = CONTENT_MARGIN_X;
			breadCrumbs.y = 10;
		}
		
		private function topLinkHandler(menuName:String):void
		{
			onTopLink.dispatch(menuName, fullPath);
		}

		private function loadBackground():void
		{
			backgroundImage = AppGlobal.PATH_BACKGROUND;
			if(backgroundImage == null)
				return;
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, backgroundImageComplete);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, backgroundOnIOError);
			loader.load(new URLRequest(AppGlobal.combinePath(backgroundImage)));
			imageBg.addChild(loader);
			readyLoadCount--;
			dispatchReady();
		}
		
		private function backgroundOnIOError(evt:IOErrorEvent):void
		{
			trace("ContentView.Image["+ backgroundImage +"].IOError: "+ evt.text);
		}		
		
		private function backgroundImageComplete(evt:Event):void
		{
			var image:DisplayObject = (evt.target as LoaderInfo).content;
		}
		
		private function initTips():void
		{
			if(tips == null)
			{
				tips = new TipsControl(content, image.width, image.height);
			}
			panel.addChild(tips);
		}

		private function setFullPath():void
		{
			var list:Array = [];
			
			var menuMain:Menu = Session.instance().menu;
			
			for each(var item:MenuChild in menuMain.childs)
			{
				if(!setRecursivePath(item, list))
				{
					list = [];
				} else {
					break;
				}
			}
		}
		
		private function setRecursivePath(menuChild:MenuChild, list:Array):Boolean
		{
			if(menuData.name == menuChild.name)
			{
				list.push(menuChild.name);
				fullPath = list.slice();
				return true;
			}
			list.push(menuChild.name);
			
			for each(var item:MenuChild in menuChild.childs)
			{
				if(!setRecursivePath(item, list))
				{
					list.pop();
				} else {
					break;
				}
			}
			return false;
		}
		
		private function initNavBarre():void
		{
			navBarre = new ContentNavBarreControl();
			panel.addChild(navBarre);
			navBarre.x = viewWidth - navBarre.width - 5;
			navBarre.y = viewHeight - navBarre.height;
			navBarre.onClicked.add(navClickHandler);
		}
		
		private function navClickHandler(sense:int):void
		{
			setNextContent(sense);
		}
		
		private function setNextContent(sense:int):void
		{
			var list:Array = Session.instance().menu.contents;
			var currentIndex:int = 0;
			for(var i:uint = 0; i<list.length; i++)
			{
				var item:MenuChild = list[i];
				if(menuData.path == item.path)
				{
					currentIndex = i;
				}
			}
			var nextIndex:int = currentIndex;
			if(currentIndex>0 && sense == 0)
			{
				nextIndex = currentIndex-1;
			}
			if(currentIndex==0 && sense == 0)
			{
				nextIndex = list.length-1;
				onNavHomeClick.dispatch();
				return;
			}
			if(currentIndex<list.length-1 && sense == 1)
			{
				nextIndex = currentIndex+1;
			}
			if(currentIndex==list.length-2 && sense == 1)
			{
				nextIndex = 0;
				onNavHomeClick.dispatch();
				return;
			}
			onNavClick.dispatch(list[nextIndex]);
		}
		
		private function getChilds():Array
		{
			var list:Array = [];
			var menuMain:Menu = Session.instance().menu;
			for each(var item:MenuChild in menuMain.childs)
			{
				setRecursiveChildList(item);
			}
			return childList;
		}

		private function setRecursiveChildList(menu:MenuChild):void
		{
			var found:Boolean = false;
			for each(var item:MenuChild in menu.childs)
			{
				if(item.name == menuData.name)
				{
					childList = menu.childs;
					found = true;
					break;
				} else {
					setRecursiveChildList(item);
				}
			}
		}

		public function dispose():void
		{
			parent.removeChild(this);
		}
		
		private function setSubContentMode():void
		{
			if(menuData.contents == null) return;
			if(menuData.contents.length == 0) return;

			var labelWidth:uint = 90;
			var btnWidth:uint = 22;
			var btnHeight:uint = 22;

			var posx:uint = scrollpane.x;
			var posy:uint = scrollpane.y + scrollpane.height + 10;

			var label:SubContentLabel = new SubContentLabel(labelWidth, btnHeight);
			panel.addChild(label);
			label.x = posx; posx += labelWidth + 2;
			label.y = posy;
			
			prevButton = new ContentArrowControl({source:menuData}, btnWidth, btnHeight, false);
			prevButton.onClicked.add(subContentClickHandler);
			panel.addChild(prevButton);

			prevButton.x = posx; posx += btnWidth + 2;
			prevButton.y = posy;

			nextButton = new ContentArrowControl({source:menuData}, btnWidth, btnHeight, true);
			nextButton.onClicked.add(subContentClickHandler);
			panel.addChild(nextButton);
			nextButton.x = posx; posx += btnWidth + 2;
			nextButton.y = posy;
		}
		
		private function subContentClickHandler(btn:ContentArrowControl):void
		{
			if(btn == prevButton)
			{
				if(menuData.indexContent > 0)
				{
					menuData.indexContent--;
				} else {
					return;
				}
			} else {
				if(menuData.indexContent < menuData.contents.length)
				{
					menuData.indexContent++;
				} else {
					return;
				}
			}
			dispatchEvent(new MenuContentEvent(MenuContentEvent.OPEN, menuData));
			dispose();
		}
	}
}
